package com.caigou.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.caigou.bean.bid.entity.BidPrivilege;
import com.caigou.bean.bid.entity.BidRolePrivXw;
import com.caigou.bean.bid.entity.BidUserRoleXw;
import com.caigou.bean.cms.entity.*;
import com.caigou.bean.cms.param.*;
import com.caigou.bean.exam.entity.UserInfo;
import com.caigou.bean.exam.entity.Users;
import com.caigou.bean.exam.param.*;
import com.caigou.bean.exam.vo.CurrentUserVO;
import com.caigou.bean.exam.vo.MsgCodeVO;
import com.caigou.bean.exam.vo.UserVO;
import com.caigou.bean.param.FunctionStaffPrivilegeParam;
import com.caigou.bean.param.PrivilegeParam;
import com.caigou.bean.vo.*;
import com.caigou.component.OSSComponent;
import com.caigou.component.RedisComponent;
import com.caigou.enums.*;
import com.caigou.exception.UserNotFoundException;
import com.caigou.mapper.bid.BidPrivilegeMapper;
import com.caigou.mapper.bid.BidRolePrivXwMapper;
import com.caigou.mapper.bid.BidUserRoleXwMapper;
import com.caigou.mapper.cms.*;
import com.caigou.mapper.exam.UserInfoMapper;
import com.caigou.mapper.exam.UsersMapper;
import com.caigou.service.IUserBaseInfoService;
import com.caigou.service.IUsersService;
import com.caigou.util.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UsersServiceImpl implements IUsersService {
    @Resource
    private IUserBaseInfoService userBaseInfoService;
    @Resource
    private UsersMapper usersMapper;
    @Resource
    private UserRoleXwMapper userRoleXwMapper;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private RolePrivilegeMapper rolePrivilegeMapper;
    @Resource
    private PrivilegeMapper privilegeMapper;
    @Resource
    private IUsersService usersService;
    @Resource
    private UserInfoMapper userInfoMapper;
    @Resource
    private UserBaseInfoMapper userBaseInfoMapper;
    @Resource
    private RedisComponent redisUtil;
    @Resource
    private FunctionBlockMapper functionBlockMapper;
    @Resource
    private UserPrivilegeMapper userPrivilegeMapper;
    @Resource
    private ArticleDictionaryUserMapper articleDictionaryUserMapper;
    @Resource
    private StaffMenuBarMapper staffMenuBarMapper;
    @Resource
    private OSSComponent ossComponent;
    @Resource
    private BidPrivilegeMapper bidPrivilegeMapper;
    @Resource
    private BidUserRoleXwMapper bidUserRoleXwMapper;
    @Resource
    private BidRolePrivXwMapper bidRolePrivXwMapper;

    @Override
    public Users findUserByTel(String tel) {
        Users user = usersMapper.findUserByTel(tel);
        return user;
    }

    /**
     * 根据用户名查询权限
     * 层级结构化权限表
     *
     * @param userName
     * @return
     */
    @Override
    public List<Privilege> findPrivilegesByUsername(String userName, Integer type) {
        UserRoleXw roleXws = userRoleXwMapper.findRolesByUserId(userName);
        if (roleXws != null) {
            return findPrivilegesByRoleIds(Arrays.asList(roleXws.getRoleCode()), type);
        }

        return null;


    }

    private void setRouterPrivilegeVO(Map<Integer, List<Privilege>> privilegesMap, List<RouterPrivilegeVO> routerPrivilegeVos, Integer start, Integer num) {
        List<Privilege> child = privilegesMap.get(start);
        if (!CollectionUtils.isEmpty(child)) {
            child.forEach(vo -> {
                RouterPrivilegeVO routerPrivilegeVO = new RouterPrivilegeVO();
                routerPrivilegeVO.setRouterId(vo.getId());
                routerPrivilegeVO.setRouterIcon(vo.getRouterIcon());
                routerPrivilegeVO.setRouterName(vo.getRouterName());
                routerPrivilegeVO.setRouterUrl(vo.getRouterUrl());
                routerPrivilegeVO.setRouterValue(vo.getRouterValue());
                routerPrivilegeVos.add(routerPrivilegeVO);
                if (num <= 0) {
                    setRouterPrivilegeVO(privilegesMap, routerPrivilegeVO.getChild(), vo.getId(), num + 1);
                }
            });
        }
    }


    /**
     * 根据角色ids查询权限
     *
     * @param
     * @return List<Privilege>
     */
    @Override
    public List<Privilege> findPrivilegesByRoleIds(List<String> roleCodes, Integer type) {
        List<RolePrivilege> rolePrivXws = rolePrivilegeMapper.findPrivilegesByRoleCodes(roleCodes);
        List<String> privilegeIds = rolePrivXws.stream().map(RolePrivilege::getPrivilegeCode).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(privilegeIds)) {
            return Collections.emptyList();
        }
        //查询出用户所有权限
        List<Privilege> privileges = privilegeMapper.findPrivilegesByPrivilegeCodes(privilegeIds);
        if (type.equals(Constant.UNSTRUCTURED_DATA)) {
            return privileges;
        }

        List<Privilege> privilegeVos = new ArrayList<>();
        //结果转换成map，并根据父类id进行分组
        Map<Integer, List<Privilege>> PrivilegesMap = privileges.stream().collect(Collectors.groupingBy(Privilege::getParentId));
        //递归存入权限数据
        setChildBusinessVo(PrivilegesMap, privilegeVos, -1, 0);

        return privilegeVos;

    }

    private void setChildBusinessVo(Map<Integer, List<Privilege>> PrivilegesMap, List<Privilege> privilegeVo, Integer start, Integer num) {
        List<Privilege> child = PrivilegesMap.get(start);
        if (!CollectionUtils.isEmpty(child)) {
            child.forEach(vo -> {
                Privilege privilege = new Privilege();
                BeanUtils.copyProperties(vo, privilege);
                privilegeVo.add(privilege);
                setChildBusinessVo(PrivilegesMap, privilege.getChildPrivilege(), vo.getId(), num + 1);
            });
        }
    }

    /**
     * 注册用户
     *
     * @param param
     * @return
     */
    @Override
    @Transactional
    public Result<Integer> registerUser(RegisterUserParam param) {
        log.info("已接收到 : " + param.getUsername() + "用户注册请求registerUser");
        //判断用户短信验证是否正确
        String redisSmsKey = Constant.SMS_PRE_KEY + param.getUsername();
        String redisSmsCode = (String) redisUtil.get(redisSmsKey);
        if (redisSmsCode == null) {
            return Result.error(ResponseEnum.MSG_ERROR);
        }
        if (redisSmsCode.equals(param.getMsgCode())) {
            //先查询用户是否注册过
            Users users = usersMapper.findUserByTel(param.getUsername());
            if (users != null) {
                return Result.error(ResponseEnum.USER_REGISTERED);
            }

            //生成6位随机字符串作为用户盐值
            String salt = UUIDUtil.getUUID().replaceAll("-", "").substring(0, 6);
            //创建用户
            Users user = new Users();
            user.setUserid(UUIDUtil.getUUID());
            user.setTel(param.getUsername());
            //设置密码
            user.setPassword(Md5Util.MD5_32bit(Md5Util.MD5_32bit(param.getPassword(), "UTF-8") + salt, "UTF-8"));
            //获取当前时间戳
            user.setAddTime(System.currentTimeMillis() / 1000);
            user.setSource(8L);//注册来源  1app 2pc 3weixin 4考试中心 5微信小程序 6易找标 8官网
            user.setRegisterStyle(8L);//注册方式  1手机 2微信 3qq 4微博 5微信小程序 6易找标  8官网
            user.setIsTel(1L);
            user.setSalt(salt);
            int insert = usersMapper.insert(user);
            if (insert == 1) {
                UserRoleXw roleXw = new UserRoleXw();
                roleXw.setUserid(user.getUserid());
                roleXw.setCreateTime(new Date());
                int insertSelective = userRoleXwMapper.insertUserRole(roleXw);
                if (insertSelective == 1) {

                    //设置用户默认基础信息
                    UserInfo userInfo = new UserInfo();
                    userInfo.setUserid(user.getUserid());
                    String invoiceId = "gw_" + System.currentTimeMillis();
                    userInfo.setNickname(invoiceId);
                    userInfo.setUserpic("https://oss.caigou2003.com/default/default.jpg");
                    userInfo.setSex(0L);
                    userInfo.setBirth("");
                    userInfo.setLoginnum(0);
                    userInfo.setOtherTel(param.getUsername());
                    int insertNum = userInfoMapper.insertSelective(userInfo);

                    return Result.success(insertNum);
                }
            }
        }
        return Result.error(ResponseEnum.MSG_ERROR);

    }

    @Override
    public Users getCurrentUserInfo() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth == null) {
            throw new UserNotFoundException(ResponseEnum.NO_TOKEN);
        }
        Users user = usersService.findUserByTel(auth.getName());
        if (user == null) {
            throw new UserNotFoundException(ResponseEnum.NO_TOKEN);
        }
        return user;
    }

    @Override
    public Result<Integer> forgotPassword(RegisterUserParam param) {
        //判断用户短信验证是否正确
        String redisSmsKey = Constant.SMS_PRE_KEY + param.getUsername();
        String redisSmsCode = (String) redisUtil.get(redisSmsKey);
        if (redisSmsCode == null) {
            return Result.error(FailResultEnum.SMS_CODE_ERROR);
        }
        if (redisSmsCode.equals(param.getMsgCode())) {
            //先查询用户是否注册过
            Users users = usersMapper.findUserByTel(param.getUsername());
            if (users == null) {
                return Result.error(FailResultEnum.NO_FIND_PHONE);
            }

            //生成6位随机字符串作为用户盐值
            String salt = UUIDUtil.getUUID().replaceAll("-", "").substring(0, 6);
            //创建用户
            Users user = new Users();
            user.setId(users.getId());
            //设置密码
            user.setPassword(Md5Util.MD5_32bit(Md5Util.MD5_32bit(param.getPassword(), "UTF-8") + salt, "UTF-8"));
            //获取当前时间戳
            user.setSalt(salt);
            int insert = usersMapper.updateByPrimaryKeySelective(user);
            return Result.success(insert);
        }
        return Result.error(FailResultEnum.SMS_CODE_ERROR);


    }

    @Override
    public Result findUsersByParam(UsersParam param) {
        PageHelper.startPage(param.getPage(), param.getSize());
        PageInfo<Users> usersPageInfo = new PageInfo<>(usersMapper.findUsersByParam(param));

        if (!CollectionUtils.isEmpty(usersPageInfo.getList())) {
            List<String> userIds = usersPageInfo.getList().stream().map(Users::getUserid).collect(Collectors.toList());
            List<UserInfo> info = userInfoMapper.findUserInfoByUserIds(userIds);
            Map<String, UserInfo> userInfoMap = info.stream().collect(Collectors.toMap(UserInfo::getUserid, Function.identity(), (k1, k2) -> k2));
            usersPageInfo.getList().forEach(userInfo -> {
                userInfo.setUserInfo(userInfoMap.get(userInfo.getUserid()));
            });

        }
        return ResultUtil.success(usersPageInfo);
    }

    @Override
    public Result findRolesByParam() {
        List<Role> roles = roleMapper.findAllRoles();
        return ResultUtil.success(roles);
    }


    @Override
    public Result<Integer> addRoleByParam(RoleParam param) {
        //角色编码生成
        String roleCode = UUIDUtil.getUUID().replaceAll("-", "").substring(0, 6).toUpperCase();
        //验证角色表里是否含有重复CD和名称
        List<Role> roles = roleMapper.findAllRoles();
        List<String> roleNames = roles.stream().map(Role::getRoleName).collect(Collectors.toList());
        List<String> roleCodes = roles.stream().map(Role::getRoleCode).collect(Collectors.toList());
        if (roleNames.contains(param.getRoleName()) || roleCodes.contains(roleCode)) {
            return Result.error(ResponseEnum.ROLE_CODE_REPEAT);
        }

        Role role = new Role();
        role.setRoleName(param.getRoleName());
        role.setRoleCode(roleCode);
        role.setCreateTime(new Date());
        int i = roleMapper.insertSelective(role);
        if (CollectionUtils.isEmpty(param.getPrivilegeCodes())) {
            return Result.error(ResponseEnum.PARAM_ERROR);
        }

        List<Privilege> privileges = privilegeMapper.findAllPrivileges();
        List<FunctionBlock> functionBlock = functionBlockMapper.findAllFunctionBlock();
        List<String> collect = functionBlock.stream().map(FunctionBlock::getFunctionCode).collect(Collectors.toList());
        List<String> privilegeCodes = privileges.stream().map(Privilege::getPrivilegeCode).collect(Collectors.toList());
        privilegeCodes.addAll(collect);

        //添加角色与权限字典表
        param.getPrivilegeCodes().forEach(privilegeCode -> {
            log.info(privilegeCodes.contains(privilegeCode) ? "正确权限:" + privilegeCode : "未知权限:" + privilegeCode);
            if (privilegeCodes.contains(privilegeCode)) {
                RolePrivilege rolePrivilege = new RolePrivilege();
                rolePrivilege.setPrivilegeCode(privilegeCode);
                rolePrivilege.setRoleCode(roleCode);
                rolePrivilege.setCreateTime(new Date());
                rolePrivilegeMapper.insertSelective(rolePrivilege);
            }
        });

        return Result.success(i);
    }

    @Override
    public Result<Integer> assignRoles(AssignRoleParam param) {
        //先验证用户是否存在
        UserBaseInfo userBaseInfo = userBaseInfoMapper.findStaffByRealName(param.getStaffName());
        if (userBaseInfo == null) {
            return Result.error(ResponseEnum.NO_FIND_STAFF);
        }
        //验证角色码是否存在
        List<Role> roles = roleMapper.findAllRoles();
        List<String> roleCodes = roles.stream().map(Role::getRoleCode).collect(Collectors.toList());
        if (!roleCodes.contains(param.getRoleCode())) {
            return Result.error(ResponseEnum.UNKNOWN_PRIVILEGE);
        }
        //删除用户原来的角色
        UserRoleXw userRoleXw = userRoleXwMapper.findRolesByUserId(userBaseInfo.getUserid());
        if (userRoleXw != null) {
            //删除用户角色
            userRoleXwMapper.deleteByPrimaryKey(userRoleXw.getId());
        }

        userPrivilegeMapper.deleteStaffPrivilegesByUserId(userBaseInfo.getUserid(), Constant.FUNCTION_TYPE);
        //赋予员工新的角色
        UserRoleXw newUserRole = new UserRoleXw();
        newUserRole.setUserid(userBaseInfo.getUserid());
        newUserRole.setRoleCode(param.getRoleCode());
        newUserRole.setCreateTime(new Date());
        int addNum = userRoleXwMapper.insertSelective(newUserRole);
        //TODO 赋予员工新的角色权限
        List<RolePrivilege> privileges = rolePrivilegeMapper.findPrivilegesByRoleCodes(Collections.singletonList(param.getRoleCode()));
        if (!CollectionUtils.isEmpty(privileges)) {
            //查询权限等级
            List<Privilege> allprivileges = privilegeMapper.findAllPrivileges();
            List<FunctionBlock> functionBlock = functionBlockMapper.findAllFunctionBlock();
            Map<String, Integer> privilegeLevelAllMap = functionBlock.stream().collect(Collectors.toMap(FunctionBlock::getFunctionCode, FunctionBlock::getFunctionLevel));
            Map<String, Integer> privilegeLevelMap = allprivileges.stream().collect(Collectors.toMap(Privilege::getPrivilegeCode, Privilege::getPrivilegeLevel));
            privilegeLevelAllMap.putAll(privilegeLevelMap);

            //构造员工角色权限list
            List<UserPrivilege> userPrivileges = new ArrayList<>();
            privileges.forEach(privilegeCode -> {
                UserPrivilege privilege = new UserPrivilege();
                privilege.setCreateTime(new Date());
                privilege.setPrivilegeCode(String.valueOf(privilegeCode.getPrivilegeCode()));
                privilege.setPrivilegeType(Constant.FUNCTION_TYPE);
                privilege.setPrivilegeLevel(privilegeLevelAllMap.get(privilegeCode.getPrivilegeCode()));
                privilege.setUserid(userBaseInfo.getUserid());
                userPrivileges.add(privilege);
            });
            userPrivilegeMapper.saveStaffPrivilegesByUserId(userPrivileges);
        }

        return Result.success(addNum);
    }


    @Override
    public List<Privilege> findAllPrivileges() {
        //List<Privilege> privilegeList = privileges.stream().sorted(Comparator.comparing(Privilege::getOrderId)).collect(Collectors.toList());
        return privilegeMapper.findAllPrivileges();
    }

    @Override
    public Result removeRoles(AssignRoleParam param) {
        //查询是否已添加过该角色
        List<UserRoleXw> list = userRoleXwMapper.findRoleByUserIdAndRowId(param);
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(bean -> {
                userRoleXwMapper.deleteByPrimaryKey(bean.getId());
            });
        }
        return ResultUtil.success("操作成功");
    }

    @Override
    public Result<List<PrivilegeVO>> findRolePrivilegesByRoleId(RoleParam param) {
        List<RolePrivilege> rolePrivileges = rolePrivilegeMapper.findPrivilegesByRoleCodes(Collections.singletonList(param.getRoleCode()));
        List<String> privilegeCodes = rolePrivileges.stream().map(RolePrivilege::getPrivilegeCode).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(privilegeCodes)) {
            return Result.success(Collections.emptyList());
        }
        List<Privilege> privileges = privilegeMapper.findPrivilegesByPrivilegeCodes(privilegeCodes);
        List<FunctionBlock> functionBlock = functionBlockMapper.findFunctionBlockByFunctionCodes(privilegeCodes);

        ArrayList<AuthorizeVO> keyValueVOS = new ArrayList<>();
        if (!CollectionUtils.isEmpty(privileges)) {
            privileges.forEach(bean -> {
                keyValueVOS.add(new AuthorizeVO(bean.getPrivilegeName(), bean.getPrivilegeCode()));
            });
        }
        if (!CollectionUtils.isEmpty(functionBlock)) {
            functionBlock.forEach(bean -> {
                keyValueVOS.add(new AuthorizeVO(bean.getFunctionName(), bean.getFunctionCode()));
            });
        }


        if (CollectionUtils.isEmpty(keyValueVOS)) {
            return Result.success(Collections.emptyList());
        }
        List<PrivilegeVO> privilegeVOS = keyValueVOS.stream().map(bean -> new PrivilegeVO(bean.getValue(), bean.getLabel())).collect(Collectors.toList());
        return Result.success(privilegeVOS);

    }

    @Override
    public Integer editUserInfo(EditUserInfoParam param) {
        UserBaseInfo userBaseInfo = new UserBaseInfo();
        BeanUtils.copyProperties(param, userBaseInfo);
        int i = userBaseInfoMapper.updateByPrimaryKeySelective(userBaseInfo);
        return i;
    }

    @Override
    public UserBaseInfo findUserInfoByUserId(String userid) {
        UserBaseInfo userBaseInfo = userBaseInfoMapper.findUserBaseInfoByUserId(userid);
        return userBaseInfo;
    }

    @Override
    public List<Privilege> findAllLevelPrivileges() {
        List<Privilege> privilegeList = findPrivilegesByRoleIds(null, Constant.STRUCTURED_DATA);
        return privilegeList;
    }

    @Override
    public Integer addPrivileges(PrivilegeParam param) {
        Privilege privilege = new Privilege();
        BeanUtils.copyProperties(param, privilege);
        privilege.setUpdateTime(LocalDateTime.now());
        privilege.setIsDelete(0);
        return privilegeMapper.insertSelective(privilege);
    }

    @Override
    public Integer editPrivileges(PrivilegeParam param) {
        Privilege privilege = new Privilege();
        BeanUtils.copyProperties(param, privilege);
        privilege.setUpdateTime(LocalDateTime.now());
        return privilegeMapper.updateByPrimaryKeySelective(privilege);
    }

    @Override
    public Integer deletePrivileges(Integer id) {
        return privilegeMapper.deleteByPrimaryKey(id);
    }

    @Override
    public Result<String> findUsersRealNameByParam(UserRealNameParam param) {
        Users user = usersService.findUserByTel(param.getUsername());
        if (user == null) {
            return Result.error("未找到该用户信息");
        }
        UserBaseInfo userBaseInfoByUserId = userBaseInfoService.findUserBaseInfoByUserId(user.getUserid());
        if (userBaseInfoByUserId == null) {
            return Result.success();
        }
        return Result.success(userBaseInfoByUserId.getRealName());
    }

    @Override
    public Result<String> addUsersRealName(UserRealNameParam param) {
        Users user = usersService.findUserByTel(param.getUsername());
        if (user == null) {
            return Result.error("未找到该用户信息");
        }
        UserBaseInfo userBaseInfo = new UserBaseInfo();
        userBaseInfo.setRealName(param.getRealName());
        userBaseInfo.setUserid(user.getUserid());
        userBaseInfo.setIsDelete(0);
        userBaseInfo.setCreateTime(new Date());
        int insert = userBaseInfoMapper.insertSelective(userBaseInfo);
        if (insert == 0) {
            return Result.error(ResponseEnum.PARAM_ERROR);
        }
        return Result.success("添加用户信息成功");
    }


    public Result<MsgCodeVO> sendSmsCode(MsgCodeParam param) {
        if (StringUtils.isEmpty(param.getTel())) {
            log.error("用户请求未填写手机号");
            return Result.error(ResponseEnum.NO_TEL);
        }
        log.info("已接收到 : " + param.getTel() + "用户请求sendSmsCode");
        //生成验证码
        String smsCode = StringUtil.genRandomNum(4);
        int time = 60 * 10;//短信验证码有效期60秒*10
        String signName = "政府采购信息网";
        String templateCode = null;
        String message = null;
        if (param.getCodeType().equals(MsgTypeEnum.MSG_REGISTER.getType())) {
            templateCode = MsgTypeEnum.MSG_REGISTER.getCode();
            message = "{\n" +
                    "\"code\":\"" + smsCode + "\"\n" + "," +
                    "\"product\":\"政府采购信息网\"\n" +
                    "}";
        } else if (param.getCodeType().equals(MsgTypeEnum.MSG_SIGN_IN.getType())) {
            templateCode = MsgTypeEnum.MSG_SIGN_IN.getCode();
            message = "{\n" +
                    "\"code\":\"" + smsCode + "\"\n" + "," +
                    "\"product\":\"政府采购信息网\"\n" +
                    "}";
        } else if (param.getCodeType().equals(MsgTypeEnum.MSG_FORGOT_PASSWORD.getType())) {
            templateCode = MsgTypeEnum.MSG_FORGOT_PASSWORD.getCode();
            message = "{\"code\":\"" + smsCode + "\"}";
        } else if (param.getCodeType().equals(MsgTypeEnum.MSG_BINDING_SEND.getType())) {
            templateCode = MsgTypeEnum.MSG_BINDING_SEND.getCode();
            message = "{\"code\":\"" + smsCode + "\"}";
        }

        String messageType = "1";
        SendSmsResponse smsRes = null;

        try {
            if (StringUtils.isEmpty(templateCode)) {
                return Result.error(ResponseEnum.MSG_MODEL_ERROR);
            }

            smsRes = SmsUtil.sendSms(signName, param.getTel(), message, templateCode, messageType);
            if (smsRes.getCode() != null && smsRes.getCode().equals("OK")) {
                log.info("向{}发送验证码成功！", param.getTel());//请求成功
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        log.info("发送给{}短信验证码{}", param.getTel(), smsCode);
        //将短信验证码加入到redis缓存
        boolean result = false;
        if (smsRes != null) {
            String redisSmsKey = Constant.SMS_PRE_KEY + param.getTel();
            result = redisUtil.set(redisSmsKey, smsCode, time);
        }
        if (result) {
            MsgCodeVO msgCodeVO = new MsgCodeVO();
            msgCodeVO.setTime(time);
            msgCodeVO.setTel(param.getTel());
            msgCodeVO.setMsg("发送短信验证码成功");
            return Result.success(msgCodeVO);
        } else {
            return Result.error(ResponseEnum.MSG_SEND_ERROR);
        }
    }

    @Override
    public Result<Integer> assignRolePrivilege(AssignRolePrivilegeParam param) {
        //校验角色编码是否正确
        List<Role> roles = roleMapper.findAllRoles();
        List<String> roleCodes = roles.stream().map(Role::getRoleCode).collect(Collectors.toList());
        if (!roleCodes.contains(param.getRoleCode())) {
            return Result.error(ResponseEnum.NO_FIND_ROLE);
        }
        List<RolePrivilege> orgRolePrivileges = rolePrivilegeMapper.findPrivilegesByRoleCodes(Arrays.asList(param.getRoleCode()));


        //判断权限是否为空
//        if (CollectionUtils.isEmpty(param.getPrivilegeCodes())) {
//            return Result.error(ResponseEnum.PARAM_ERROR);
//        }
        //校验权限编码是否正确
        //删除角色原有权限信息
        int deleteNum = rolePrivilegeMapper.deleteByRoleCode(param.getRoleCode());
        //查询所有权限码
        List<Privilege> privileges = privilegeMapper.findAllPrivileges();
        //查询功能权限编码
        List<FunctionBlock> functionBlock = functionBlockMapper.findAllFunctionBlock();
        List<String> collect = functionBlock.stream().map(FunctionBlock::getFunctionCode).collect(Collectors.toList());
        List<String> privilegeCodes = privileges.stream().map(Privilege::getPrivilegeCode).collect(Collectors.toList());
        privilegeCodes.addAll(collect);

        List<UserPrivilege> updateAfterRolePrivileges = new ArrayList<>();
        if (!CollectionUtils.isEmpty(param.getPrivilegeCodes())) {
            param.getPrivilegeCodes().forEach(privilegeCode -> {
                //添加角色新权限
                log.info(privilegeCodes.contains(privilegeCode) ? "添加正确权限:" + privilegeCode : "未知权限码:" + privilegeCode);
                if (privilegeCodes.contains(privilegeCode)) {

                    //保存修改后该角色下所有权限
                    UserPrivilege userPrivilege = new UserPrivilege();
                    userPrivilege.setPrivilegeCode(privilegeCode);
                    updateAfterRolePrivileges.add(userPrivilege);

                    //更新角色模板
                    RolePrivilege rolePrivilege = new RolePrivilege();
                    rolePrivilege.setRoleCode(param.getRoleCode());
                    rolePrivilege.setPrivilegeCode(privilegeCode);
                    rolePrivilege.setCreateTime(new Date());
                    int insertNum = rolePrivilegeMapper.insertSelective(rolePrivilege);
                }
            });
        }
        //修改角色名称
        roleMapper.updateRoleNameByRoleCode(param.getRoleCode(), param.getRoleName());
        //修改完角色模板后更新该角色操作权限
        List<UserRoleXw> roleCodes1 = userRoleXwMapper.findUserRoleByRoleCodes(Collections.singletonList(param.getRoleCode()));
        if (!CollectionUtils.isEmpty(roleCodes1)) {
            List<String> userIds = roleCodes1.stream().map(UserRoleXw::getUserid).collect(Collectors.toList());
            List<UserPrivilege> totalPrivilege = userPrivilegeMapper.findUserOperatePrivilegeByUserIds(userIds);
            Map<String, Integer> privilegeLevelAllMap = functionBlock.stream().collect(Collectors.toMap(FunctionBlock::getFunctionCode, FunctionBlock::getFunctionLevel));

            //查询原来

            totalPrivilege.stream().collect(Collectors.groupingBy(UserPrivilege::getUserid)).forEach((key, values) -> {
                List<String> userPrivilegeCode = values.stream().map(UserPrivilege::getPrivilegeCode).collect(Collectors.toList());
                //原始员工权限编码
                List<String> orgRolePrivilegeCode = orgRolePrivileges.stream().map(RolePrivilege::getPrivilegeCode).collect(Collectors.toList());
                //收集需要增加的权限
                List<String> addPrivilegeCode = new ArrayList<>();
                userPrivilegeCode.forEach(privilegeCode -> {
                    if (!orgRolePrivilegeCode.contains(privilegeCode)) {
                        addPrivilegeCode.add(privilegeCode);
                    }
                });

                //收集需要减少的权限
                List<String> deletePrivilegeCode = new ArrayList<>();
                orgRolePrivilegeCode.forEach(privilegeCode -> {
                    if (!userPrivilegeCode.contains(privilegeCode)) {
                        deletePrivilegeCode.add(privilegeCode);
                    }
                });

                //总结最终权限

                List<String> finalPrivilegeCode = updateAfterRolePrivileges.stream().map(UserPrivilege::getPrivilegeCode).collect(Collectors.toList());
                finalPrivilegeCode.addAll(addPrivilegeCode);
                finalPrivilegeCode.removeAll(deletePrivilegeCode);

                //删除旧数据
                userPrivilegeMapper.deleteStaffPrivilegesByUserId(key, Constant.FUNCTION_TYPE);

                //添加新数据
                List<UserPrivilege> finalPrivileges = new ArrayList<>();

                finalPrivilegeCode.forEach(privilegeCode -> {
                    UserPrivilege privilege = new UserPrivilege();
                    privilege.setCreateTime(new Date());
                    privilege.setPrivilegeCode(privilegeCode);
                    privilege.setPrivilegeType(Constant.FUNCTION_TYPE);
                    privilege.setPrivilegeLevel(privilegeLevelAllMap.get(privilegeCode) != null ? privilegeLevelAllMap.get(privilegeCode) : 3);
                    privilege.setUserid(key);
                    finalPrivileges.add(privilege);
                });
                userPrivilegeMapper.saveStaffPrivilegesByUserId(finalPrivileges);

            });
        }

        return Result.success(param.getPrivilegeCodes().size());
    }

    @Override
    public CurrentUserVO currentUser(String username) {

        //获取用户信息
        Users user = findUserByTel(username);
        if (user != null) {
            CurrentUserVO currentUserVO = new CurrentUserVO();

            //查询用户详情信息
            CompletableFuture<UserBaseInfo> userBaseInfoFuture = CompletableFuture.supplyAsync(() ->
                    userBaseInfoService.findUserBaseInfoByUserId(user.getUserid()));

            //查询用户权限
            CompletableFuture<List<Privilege>> privilegesFuture = CompletableFuture.supplyAsync(() ->
                    findPrivilegesByUsername(user.getUserid(), Constant.STRUCTURED_DATA));


            //查询用户角色
            CompletableFuture<UserRoleXw> roleXwsFuture = CompletableFuture.supplyAsync(() ->
                    userRoleXwMapper.findRolesByUserId(user.getUserid()));

            CompletableFuture.allOf(userBaseInfoFuture, privilegesFuture, roleXwsFuture).join();

            UserBaseInfo userBaseInfo = userBaseInfoFuture.join();
            List<Privilege> privileges = privilegesFuture.join();
            UserRoleXw roleXws = roleXwsFuture.join();

            //设置用户基础信息
            if (userBaseInfo != null) {
                currentUserVO.setUserBaseInfo(userBaseInfo);
            }
            //设置用户权限
            currentUserVO.setPrivileges(privileges);


            //根据角色id查询角色名称

            if (roleXws == null) {
                //return ResultUtil.error(403, "未找到该用户权限,请重新登录");
                currentUserVO.setRole(null);
                return currentUserVO;
            }
            Role roles = roleMapper.findRoleByRoleCode(roleXws.getRoleCode());
            //设置用户角色
            currentUserVO.setRole(roles);

            return currentUserVO;
        }

        return null;
    }


    public Result queryUser(UsersParam param) {
        String[] labels = param.getLabels();
        if (labels != null && labels.length > 0) {
            List<String> userIdListByLabels = usersMapper.listUserIdByLabels(labels);
            if (!userIdListByLabels.isEmpty()) {
                param.setUserIdListByLabels(userIdListByLabels);
            }
        }
        PageHelper.startPage(param.getPage(), param.getSize());
        List<Users> usersList = usersMapper.queryUser(param);
        PageInfo<Users> usersPageInfo = new PageInfo<>(usersList);
        return Result.success(usersPageInfo);
    }

    public Result updateUserStatus(UsersParam param) {
        int ucount = usersMapper.updateUserStatus(param);
        if (ucount > 0) {
            return Result.success("修改用户禁言/禁用状态成功");
        } else {
            return Result.error("修改用户禁言/禁用状态失败");
        }
    }

    public Result updateTel(UsersUpdateParam param) {
        int ucount = usersMapper.updateTel(param);
        if (ucount > 0) {
            return Result.success("修改手机号码成功");
        } else {
            return Result.error("修改手机号码失败");
        }
    }

    public Result updatePassword(UsersUpdateParam param) {
        String userId = param.getUserId();
        Users user = usersMapper.findUserByUserId(userId);
        if (user == null) {
            return Result.error("修改密码失败，没有该用户");
        } else {
            String salt = user.getSalt();
            String newPassword = param.getNewPassword();
            String pwd1 = Md5Util.MD5_32bit(newPassword, "UTF-8");
            String password = Md5Util.MD5_32bit(pwd1 + salt, "UTF-8");
            param.setNewPassword(password);
            int ucount = usersMapper.updatePassword(param);
            if (ucount > 0) {
                return Result.success("修改密码成功");
            } else {
                return Result.error("修改密码失败");
            }
        }
    }

    /**
     * 获取用户详情
     *
     * @param param
     * @return
     */
    public Result<UserVO> queryUserDetail(UsersParam param) {
        String userId = param.getUserId();
        Users user = usersMapper.queryUserDetail(userId);
        List<String> labelNames = listLabelNameByUserId(userId);
        int modalCount = usersMapper.getModalCountByUserId(userId);
        Integer cityId = user.getUserInfo().getCity();
        String areaName = null;
        if (cityId != null) {
            areaName = getAreaNameById(cityId);
        }
        UserInfo userInfo = userInfoMapper.findUserInfoByUserId(userId);


        UserVO userVO = new UserVO();
        userVO.setUser(user);
        userVO.setLabels(labelNames);
        userVO.setModalCount(modalCount);
        userVO.setAreaName(areaName);
        if (userInfo != null) {
            userVO.setFrontUserDepartment(userInfo.getDepart());
            userVO.setFrontUserDuty(userInfo.getWorker());
            userVO.setFrontUserLocation(areaName);
        }

        return Result.success(userVO);
    }

    public List<String> listLabelNameByUserId(String userId) {
        List<String> labelIds = usersMapper.listLabelIdByUserId(userId);
        List<String> stringList = labelIds.stream().filter(str -> !StringUtils.isEmpty(str)).distinct().collect(Collectors.toList());


        if (stringList.size() > 0) {
            List<Integer> labelIdList = new ArrayList<>(stringList.size());
            for (String labelId : stringList) {
                Integer id = Integer.parseInt(labelId);
                labelIdList.add(id);
            }
            List<String> labelNames = usersMapper.listLabelNameByLabelIds(labelIdList);
            return labelNames;
        } else {
            return null;
        }
    }

    public String getAreaNameById(Integer id) {
        return usersMapper.getAreaNameById(id);
    }

    @Override
    public Result<StaffPrivilegesVO> findStaffPrivilegesByParam(FunctionStaffPrivilegeParam param) {
        if (StringUtils.isEmpty(param.getStaffId())) {
            return Result.error(ResponseEnum.NO_STAFF_ID);
        }
        UserBaseInfo staff = userBaseInfoMapper.findStaffByStaffId(param.getStaffId());
        if (!"U00000000".equals(param.getStaffId())) {
            if (staff == null) {
                return Result.error(ResponseEnum.NO_FIND_STAFF);
            }
        }
        StaffPrivilegesVO staffPrivilegesVO = new StaffPrivilegesVO();
        //1、用户权限层级列表
        List<FunctionBlock> functionBlocks = functionBlockMapper.findAllFunctionBlock();
        Map<String, List<FunctionBlock>> functionBlockMaps = functionBlocks.stream().collect(Collectors.groupingBy(FunctionBlock::getParentCode));
        List<Privilege> privileges = privilegeMapper.findAllPrivileges();


        //Map<String, String> functionBlockMap = privileges.stream().filter(bean -> bean.getFunctionBlockCode() != null).collect(Collectors.toMap(Privilege::getPrivilegeCode, Privilege::getPrivilegeName));
        Map<String, List<Privilege>> functionBlockMap = privileges.stream().filter(bean -> bean.getFunctionBlockCode() != null).collect(Collectors.groupingBy(Privilege::getFunctionBlockCode));

        List<String> privilegeCodes = new ArrayList<>();

        //2、用户权限
        List<UserPrivilege> userPrivileges = new ArrayList<>();

        List<String> roles = param.getPrivilegeCodes();
        List<String> rolePrivilegeCodes = new ArrayList<>();
        if (!CollectionUtils.isEmpty(roles)) {
            //去掉当前用户的角色,防止员工管理-角色与权限回显出传入的权限
            List<RolePrivilege> rolePrivileges = rolePrivilegeMapper.findPrivilegesByRoleCodes(roles);
            if (!CollectionUtils.isEmpty(rolePrivileges)) {
                rolePrivilegeCodes = rolePrivileges.stream().map(RolePrivilege::getPrivilegeCode).collect(Collectors.toList());
            }
        }

        //查询角色下对应权限

        if (staff != null) {
            String userid = staff.getUserid();
            UserRoleXw userRoleXw = userRoleXwMapper.findRolesByUserId(userid);
            if (userRoleXw != null && !StringUtils.isEmpty(userRoleXw.getRoleCode()) && !CollectionUtils.isEmpty(param.getPrivilegeCodes()) && param.getPrivilegeCodes().stream().findFirst().isPresent() && param.getPrivilegeCodes().stream().findFirst().get().equals(userRoleXw.getRoleCode())) {
                //查询出用户现有的所有权限
                userPrivileges = userPrivilegeMapper.findUserOperatePrivilegeByUserId(staff.getUserid(), Constant.FUNCTION_TYPE);
                privilegeCodes = userPrivileges.stream().map(UserPrivilege::getPrivilegeCode).collect(Collectors.toList());
                privilegeCodes.addAll(!CollectionUtils.isEmpty(rolePrivilegeCodes) ? privilegeCodes : Collections.emptyList());
                rolePrivilegeCodes.clear();

            }
            List<String> collect = privileges.stream().map(Privilege::getPrivilegeCode).collect(Collectors.toList());
            privilegeCodes.addAll(collect);
            List<String> allPrivilegeCodes = privilegeCodes.stream().distinct().collect(Collectors.toList());
            staffPrivilegesVO.setPrivilegeCode(allPrivilegeCodes);

        } else {
            staffPrivilegesVO.setPrivilegeCode(Collections.emptyList());
        }

        List<FunctionPrivilegeVO> keyValueVOS = new ArrayList<>();
        if (!CollectionUtils.isEmpty(functionBlocks)) {
            setChildBusinessVo(functionBlockMaps, keyValueVOS, "root", functionBlockMap, 1, privilegeCodes, userPrivileges, rolePrivilegeCodes);
        }
        staffPrivilegesVO.setKeyValueVOS(keyValueVOS);
        return Result.success(staffPrivilegesVO);
    }

    private void setChildBusinessVo(Map<String, List<FunctionBlock>> PrivilegesMap, List<FunctionPrivilegeVO> keyValueVOS, String start, Map<String, List<Privilege>> functionBlockMap, Integer level, List<String> privilegeCodes, List<UserPrivilege> userPrivileges, List<String> rolePrivilegeCodes) {
        if (level == 3) {
            setChildPrivileges(functionBlockMap, keyValueVOS, start, userPrivileges, rolePrivilegeCodes);
        }

        List<FunctionBlock> child = PrivilegesMap.get(start);
        if (!CollectionUtils.isEmpty(child)) {
            child.forEach(vo -> {
                FunctionPrivilegeVO keyValueVO = new FunctionPrivilegeVO();
                keyValueVO.setLabel(vo.getFunctionName());
                keyValueVO.setValue(vo.getFunctionCode());
                if (privilegeCodes.contains(vo.getFunctionCode()) || rolePrivilegeCodes.contains(vo.getFunctionCode())) {
                    keyValueVO.setSelected(true);
                } else {
                    keyValueVO.setSelected(false);
                }
                keyValueVOS.add(keyValueVO);
                setChildBusinessVo(PrivilegesMap, keyValueVO.getChildren(), vo.getFunctionCode(), functionBlockMap, (1 + level), privilegeCodes, userPrivileges, rolePrivilegeCodes);

            });
        }
    }

    @Override
    public Result<Integer> saveStaffPrivilegesByUserId(FunctionStaffPrivilegeParam param) {
        log.info("接受到调整权限的参数-{}", param);

        if (StringUtils.isEmpty(param.getStaffId())) {
            return Result.error(ResponseEnum.NO_STAFF_ID);
        }
        UserBaseInfo staff = userBaseInfoMapper.findStaffByStaffId(param.getStaffId());
        if (staff == null) {
            return Result.error(ResponseEnum.NO_FIND_STAFF);
        }

        //验证用户传入权限编码是否正确
        List<FunctionBlock> functionBlock = functionBlockMapper.findAllFunctionBlock();
        List<String> functionCodes = functionBlock.stream().map(FunctionBlock::getFunctionCode).collect(Collectors.toList());
        List<Privilege> privileges = privilegeMapper.findAllPrivileges();
        List<String> privilegesCodes = privileges.stream().map(Privilege::getPrivilegeCode).collect(Collectors.toList());
        functionCodes.addAll(privilegesCodes);
        for (String code : param.getPrivilegeCodes()) {
            if (!functionCodes.contains(code)) {
                log.info("未知权限参数={}", code);
                return Result.error(ResponseEnum.PRIVILEGE_ERROR);
            }
        }
        Map<String, Integer> allPrivilegeCodeLevel = functionBlock.stream().collect(Collectors.toMap(FunctionBlock::getFunctionCode, FunctionBlock::getFunctionLevel));
        allPrivilegeCodeLevel.putAll(privileges.stream().collect(Collectors.toMap(Privilege::getPrivilegeCode, Privilege::getPrivilegeLevel)));

        //先清除用户之前数据
        int deleteNum = userPrivilegeMapper.deleteStaffPrivilegesByUserId(staff.getUserid(), Constant.FUNCTION_TYPE);
        if (!CollectionUtils.isEmpty(param.getPrivilegeCodes())) {
            List<UserPrivilege> userPrivileges = new ArrayList<>();
            param.getPrivilegeCodes().forEach(privilegeCode -> {
                UserPrivilege privilege = new UserPrivilege();
                privilege.setCreateTime(new Date());
                privilege.setPrivilegeCode(privilegeCode);
                privilege.setPrivilegeType(Constant.FUNCTION_TYPE);
                privilege.setPrivilegeLevel(allPrivilegeCodeLevel.get(privilegeCode));
                privilege.setUserid(staff.getUserid());
                userPrivileges.add(privilege);
            });
            int insertNum = userPrivilegeMapper.saveStaffPrivilegesByUserId(userPrivileges);
        }

        UserRoleXw userRoleXw = userRoleXwMapper.findRoleByUserId(staff.getUserid());
        UserRoleXw roleXw = new UserRoleXw();
        if (userRoleXw != null) {
            roleXw.setId(userRoleXw.getId());
            roleXw.setUserid(staff.getUserid());
            roleXw.setRoleCode(param.getRoleCode());
            userRoleXwMapper.updateByPrimaryKeySelective(roleXw);
        } else {
            roleXw.setUserid(staff.getUserid());
            roleXw.setRoleCode(param.getRoleCode());
            roleXw.setCreateTime(new Date());
            userRoleXwMapper.insertSelective(roleXw);
        }

        return Result.success();
    }

    @Override
    public Result<List<RoleUserVO>> findRolesUser() {
        List<Role> roles = roleMapper.findAllRoles();
        if (CollectionUtils.isEmpty(roles)) {
            return Result.error(ResponseEnum.NO_FIND_ROLE);
        }
        List<String> roleCodes = roles.stream().map(Role::getRoleCode).distinct().collect(Collectors.toList());
        List<UserRoleXw> userRoleXws = userRoleXwMapper.findUserRoleByRoleCodes(roleCodes);
        if (CollectionUtils.isEmpty(userRoleXws)) {
            return Result.error(ResponseEnum.NO_FIND_STAFF);
        }

        Map<String, List<UserRoleXw>> roleCodeMap = userRoleXws.stream().collect(Collectors.groupingBy(UserRoleXw::getRoleCode));
        List<String> userIds = userRoleXws.stream().distinct().map(UserRoleXw::getUserid).distinct().collect(Collectors.toList());
        List<UserBaseInfo> userBaseInfos = userBaseInfoMapper.findUserBaseInfoByUserIds(userIds);
        Map<String, String> userIdTrueNameMap = userBaseInfos.stream().collect(Collectors.toMap(UserBaseInfo::getUserid, UserBaseInfo::getRealName));

        List<RoleUserVO> roleUserVOS = new ArrayList<>();
        roles.forEach(role -> {
            RoleUserVO RoleUserVO = new RoleUserVO();
            RoleUserVO.setRoleCode(role.getRoleCode());
            RoleUserVO.setRoleName(role.getRoleName());

            List<UserRoleXw> userRoleXws1 = roleCodeMap.get(role.getRoleCode());
            if (!CollectionUtils.isEmpty(userRoleXws1)) {
                List<String> staffNames = new ArrayList<>();
                userRoleXws1.stream().map(UserRoleXw::getUserid).collect(Collectors.toList()).forEach(userId -> {
                    String staffName = userIdTrueNameMap.get(userId);
                    if (!StringUtils.isEmpty(staffName)) {
                        staffNames.add(staffName);
                    }
                });
                RoleUserVO.setStaffNames(staffNames);
            }
            roleUserVOS.add(RoleUserVO);
        });
        return Result.success(roleUserVOS);
    }


    private void setChildPrivileges(Map<String, List<Privilege>> functionBlockMap, List<FunctionPrivilegeVO> children, String start, List<UserPrivilege> userPrivileges, List<String> rolePrivilegeCodes) {
        List<String> collect = userPrivileges.stream().map(UserPrivilege::getPrivilegeCode).collect(Collectors.toList());

        List<Privilege> privilegeList = functionBlockMap.get(start);
        if (!CollectionUtils.isEmpty(privilegeList)) {
            privilegeList.forEach(bean -> {
                FunctionPrivilegeVO keyValueVO = new FunctionPrivilegeVO();
                keyValueVO.setLabel(bean.getPrivilegeName());
                keyValueVO.setValue(bean.getPrivilegeCode());
                keyValueVO.setDescription(bean.getDescription());
                if (collect.contains(bean.getPrivilegeCode()) || rolePrivilegeCodes.contains(bean.getPrivilegeCode())) {
                    keyValueVO.setSelected(true);
                } else {
                    keyValueVO.setSelected(false);
                }
                children.add(keyValueVO);

            });
        }
    }

    public int getReceiveSystemMessageUserCount(Integer publishTime) {
        return usersMapper.getReceiveSystemMessageUserCount(publishTime);
    }

    @Override
    public Result<UserRegisterVO> findUserRegisterByParam(UserRegisterParam param) {
        UserRegisterVO userRegisterVO = new UserRegisterVO();
        String phoneNumber = param.getPhoneNumber();
        Users user = usersMapper.findUserByTel(phoneNumber);
        userRegisterVO.setUserStatus(user != null ? user.getUserStatus() : -1L);
        //TODO  预留字段 后续需要添加真实
        userRegisterVO.setWxOpenId("openidopenidopenidopenidopenid");
        return Result.success(userRegisterVO);
    }

    @Override
    public Result<Integer> deleteRoleByRoleCode(RoleParam param) {
        //查询角色下是否含有用户
        List<UserRoleXw> userRoleXws = userRoleXwMapper.findUserRoleByRoleCodes(Collections.singletonList(param.getRoleCode()));
        if (!CollectionUtils.isEmpty(userRoleXws)) {
            return Result.error(ResponseEnum.HAS_USER_ERROR);
        }
        Integer deleteNum = roleMapper.deleteByRoleCode(param.getRoleCode());
        return Result.success(deleteNum);
    }

    @Override
    public List<UserPrivilege> findPrivilegeCodesByUserId(String userId) {
        return userPrivilegeMapper.findPrivilegeCodesByUserId(userId);
    }

    @Override
    public Result<List<PrivilegeVO>> findStaffPrivilegesByUserId(String userId) {
        UserBaseInfo staff = userBaseInfoMapper.findUserBaseInfoByUserId(userId);
        if (staff == null) {
            return Result.error(ResponseEnum.NO_FIND_STAFF);
        }
        List<StaffMenuBar> allStaffMenu = staffMenuBarMapper.findAllStaffMenu();
        Map<String, List<StaffMenuBar>> staffMenuBarMap = allStaffMenu.stream().collect(Collectors.groupingBy(StaffMenuBar::getParentCode));

        List<PrivilegeVO> privilegeVOS = new ArrayList<>();

        setChildStaffMenuBar(privilegeVOS, staffMenuBarMap, "root", 1);

        //查询员工页面发布权权限
        List<UserPrivilege> publishPrivileges = userPrivilegeMapper.findPublishPrivilegeByUserId(userId);
        if (!CollectionUtils.isEmpty(publishPrivileges)) {
            List<String> values = publishPrivileges.stream().map(UserPrivilege::getPrivilege3Code).filter(privilege3Code -> privilege3Code.length() >= 3).distinct().collect(Collectors.toList());

            //TODO 后续添加权限icon

            List<ArticleDictionaryUser> dictionaryList = articleDictionaryUserMapper.findByValues(values);
            List<PrivilegeVO> privilegeVOList = dictionaryList.stream().map(bean -> new PrivilegeVO(bean.getValue().toString(), bean.getName(), 2)).collect(Collectors.toList());


            for (int i = privilegeVOS.size() - 1; i >= 0; i--) {
                if ("pindaoguanli".equals(privilegeVOS.get(i).getPrivilegeCode())) {
                    privilegeVOS.get(i).setChildPrivilegeVos(privilegeVOList);
                }
            }

        } else {
            for (int i = privilegeVOS.size() - 1; i >= 0; i--) {
                if ("pindaoguanli".equals(privilegeVOS.get(i).getPrivilegeCode())) {
                    privilegeVOS.remove(i);
                }
            }
        }


        List<PrivilegeVO> privilegeVOSOrg = new ArrayList<>();
        //查询出所有三级功能操作权限
        List<UserPrivilege> userPrivileges = userPrivilegeMapper.findPrivilegeByUserIdAnd3Level(userId, Constant.FUNCTION_TYPE);
        //查询员工三级操作权限
        List<String> privilege3Code = userPrivileges.stream().map(UserPrivilege::getPrivilegeCode).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(privilege3Code)) {
            return Result.success(Collections.emptyList());
        }

        List<Privilege> privilege3List = privilegeMapper.findPrivilegesByPrivilegeCodes(privilege3Code);
        List<String> privilege2Code = privilege3List.stream().map(Privilege::getFunctionBlockCode).distinct().collect(Collectors.toList());
        privilege3List.forEach(bean -> {
            privilegeVOSOrg.add(new PrivilegeVO(bean.getPrivilegeCode(), bean.getPrivilegeName(), bean.getPrivilegeLevel(), bean.getFunctionBlockCode()));
        });


        //查询二级权限
        List<FunctionBlock> functionBlock2List = functionBlockMapper.findFunctionBlockByFunctionCodes(privilege2Code);
        List<String> functionBlock1Code = functionBlock2List.stream().map(FunctionBlock::getParentCode).distinct().collect(Collectors.toList());
        functionBlock2List.forEach(bean -> {
            privilegeVOSOrg.add(new PrivilegeVO(bean.getFunctionCode(), bean.getFunctionName(), bean.getFunctionLevel(), bean.getParentCode(), bean.getFunctionIcon()));
        });

        //查询一级权限
        List<FunctionBlock> functionBlock1List = functionBlockMapper.findFunctionBlockByFunctionCodes(functionBlock1Code);
        functionBlock1List.forEach(bean -> {
            privilegeVOSOrg.add(new PrivilegeVO(bean.getFunctionCode(), bean.getFunctionName(), bean.getFunctionLevel(), bean.getParentCode(), bean.getFunctionIcon()));
        });

        //由于稿件库权限和采集内容库权限一致 则 有稿件库权限就有采集内容权限
        if (!CollectionUtils.isEmpty(privilegeVOSOrg.stream().filter(bean -> bean.getPrivilegeCode().equals("gaojiankuzhuanti")).collect(Collectors.toList())) &&
                CollectionUtils.isEmpty(privilegeVOSOrg.stream().filter(bean -> bean.getPrivilegeCode().equals("caijineirongku")).collect(Collectors.toList()))) {
            for (int i = 0; i < privilegeVOSOrg.size(); i++) {
                if (privilegeVOSOrg.get(i).getPrivilegeCode().equals("gaojiankuzhuanti")) {
                    privilegeVOSOrg.add(i + 1, new PrivilegeVO("caijineirongku", "采集内容库", 2, "neirongguanli", null));
                }
            }
        }
        //2、用户权限
        if (CollectionUtils.isEmpty(privilegeVOSOrg)) {
            return Result.success(Collections.emptyList());
        }
        Map<Integer, List<PrivilegeVO>> functionBlockMap = privilegeVOSOrg.stream().collect(Collectors.groupingBy(PrivilegeVO::getPrivilegeLevel));
        List<PrivilegeVO> privilegeVOList = new ArrayList<>();
        setChildPrivilegeVo(functionBlockMap, privilegeVOList, "root", 1);


        //重新组装返回员工菜单栏
        Map<String, PrivilegeVO> privilegeVOMap = privilegeVOList.stream().collect(Collectors.toMap(PrivilegeVO::getPrivilegeCode, bean -> bean));


        List<PrivilegeVO> collect = privilegeVOS.stream().map(bean ->
                privilegeVOMap.get(bean.getPrivilegeCode()) != null ? privilegeVOMap.get(bean.getPrivilegeCode()) : bean
        ).filter(Objects::nonNull).filter(bean -> {
            if (bean.getPrivilegeName().equals("客户服务管理")) {
                return !CollectionUtils.isEmpty(bean.getChildPrivilegeVos());
            }
            if (bean.getPrivilegeName().equals("个人中心")) {
                return privilege3Code.contains("gaojiankuchaxun");
            }
            if (bean.getPrivilegeName().equals("系统管理")) {
                if (!CollectionUtils.isEmpty(bean.getChildPrivilegeVos())) {
                    List<PrivilegeVO> filterChildPrivilegeVos = bean.getChildPrivilegeVos().stream().filter(child2Privilege -> (!child2Privilege.getPrivilegeName().equals("稿件库回收站")
                            && !child2Privilege.getPrivilegeName().equals("图片库回收站") && !child2Privilege.getPrivilegeName().equals("音频库回收站")
                            && !child2Privilege.getPrivilegeName().equals("视频库回收站"))).collect(Collectors.toList());
                    bean.setChildPrivilegeVos(filterChildPrivilegeVos);
                }
                return functionBlock1Code.contains("xitongguanli");
            }

            if (bean.getPrivilegeName().equals("内容管理")) {
                return functionBlock1Code.contains("neirongguanli");
            }

            return true;

        }).collect(Collectors.toList());

        //去除客户服务管理无权限栏目


        return Result.success(collect);
    }

    private void setChildStaffMenuBar(List<PrivilegeVO> privilegeVOS, Map<String, List<StaffMenuBar>> staffMenuBarMap, String root, int level) {

        List<StaffMenuBar> staffMenuBars = staffMenuBarMap.get(root);
        if (!CollectionUtils.isEmpty(staffMenuBars)) {
            staffMenuBars.forEach(vo -> {
                PrivilegeVO privilegeVO = new PrivilegeVO();
                privilegeVO.setPrivilegeName(vo.getMenuName());
                privilegeVO.setPrivilegeCode(vo.getMenuCode());
                privilegeVO.setPrivilegeLevel(vo.getMenuLevel());
                privilegeVO.setPrivilegeIcon(vo.getMenuIcon());
                privilegeVOS.add(privilegeVO);
                setChildStaffMenuBar(privilegeVO.getChildPrivilegeVos(), staffMenuBarMap, vo.getMenuCode(), (1 + level));
            });
        }

    }

    @Override
    @Transactional(transactionManager = "txManager", propagation = Propagation.REQUIRED, rollbackFor = {java.lang.Exception.class})
    public Result<Integer> updateStaffTel(UsersUpdateParam param) {
        if (StringUtils.isEmpty(param.getUserId())) {
            return Result.error(ResponseEnum.NO_STAFF_ID);
        }
        UserBaseInfo userBaseInfo = userBaseInfoMapper.findUserBaseInfoByUserId(param.getUserId());
        if (userBaseInfo == null) {
            return Result.error(ResponseEnum.NO_FIND_STAFF);
        }

        Users userByTel = usersMapper.findUserByTel(param.getNewTel());
        if (userByTel != null) {
            return Result.error(ResponseEnum.REPEAT_PHONE_NUMBER);
        }
        int ucount = usersMapper.updateTel(param);
        int updateNum = userBaseInfoMapper.updateStaffTel(param);

        if (ucount == 0 || updateNum == 0) {
            return Result.error(ResponseEnum.UPDATE_TEL_ERROR);
        } else {
            return Result.success(1);
        }
    }

    @Override
    public Result<Boolean> findUserHasRecycleAuthority(Integer privilegeType, String userid) {
        RecycleTypeEnum typeEnum = RecycleTypeEnum.getRecycleTypeEnum(privilegeType);
        if (typeEnum == null) {
            return Result.error(ResponseEnum.UNKNOWN_PRIVILEGE);
        }
        UserPrivilege userPrivilege = userPrivilegeMapper.findPrivilegeByUserIdAndCode(userid, typeEnum.getCode());
        return Result.success(userPrivilege != null);
    }

    @Override
    public Result<UserInfo> getUserInfoByUserId(String userid) {
        UserInfo userInfo = userInfoMapper.findUserInfoByUserId(userid);
        return Result.success(userInfo);
    }

    private void setChildPrivilegeVo(Map<Integer, List<PrivilegeVO>> PrivilegesMap, List<PrivilegeVO> privilegeVOList, String parentPrivilegeCode, Integer level) {
        List<PrivilegeVO> privilegeVOS = PrivilegesMap.get(level);
        if (!CollectionUtils.isEmpty(privilegeVOS)) {
            privilegeVOS.forEach(vo -> {
                if (parentPrivilegeCode.equals(vo.getParentPrivilegeCode())) {

                    PrivilegeVO privilegeVO = new PrivilegeVO();
                    privilegeVO.setPrivilegeName(vo.getPrivilegeName());
                    privilegeVO.setPrivilegeCode(vo.getPrivilegeCode());
                    privilegeVO.setPrivilegeLevel(vo.getPrivilegeLevel());
                    privilegeVO.setPrivilegeIcon(vo.getPrivilegeIcon());
                    privilegeVOList.add(privilegeVO);
                    setChildPrivilegeVo(PrivilegesMap, privilegeVO.getChildPrivilegeVos(), vo.getPrivilegeCode(), (1 + level));
                }

            });
        }

    }

    /**
     * 获取账户信息
     *
     * @param userId
     * @return
     */
    @Override
    public Result getUserDetailByUserId(String userId) {
        Users user = usersMapper.queryUserDetail(userId);
        return Result.success(user);
    }

    /**
     * 更新账户信息
     *
     * @param param
     * @return
     */
    @Override
    public Result updateUserDetail(UserDetailParam param) {
        UserInfo userInfo = new UserInfo();
        BeanUtil.copyProperties(param, userInfo);
        userInfo.setUserid(param.getUserId());
        int result = userInfoMapper.updateByUserIdSelective(userInfo);
        if (result > 0) {
            return Result.success(result);
        } else {
            return Result.error(result);
        }
    }

    /**
     * 上传用户头像
     *
     * @param multipartFile
     * @param userId
     * @return
     */
    @Override
    public Result uploadImage(MultipartFile multipartFile, String userId) {
        try {
            String fileName = multipartFile.getOriginalFilename();
            log.info("fileName={}", fileName);
            String fileExtension = "";
            int idx = fileName.lastIndexOf(".");
            if (idx > 0) {
                fileExtension = fileName.substring(idx);
            } else {
                log.error("上传文件错误，没有扩展名, fileName={}", fileName);
                return Result.error("上传文件错误，没有扩展名", "上传文件错误，没有扩展名");
            }
            //文件重命名
            String newFileName = userId + fileExtension;
            //上传原图
            InputStream originInputStream = multipartFile.getInputStream();
            String imageFolder = "headImage/" + userId.substring(0, 2) + "/" + userId.substring(2, 4) + "/";
            String fileUrl = ossComponent.uploadToOSS(originInputStream, fileName, newFileName, imageFolder);
            log.info("imageFolder={}, 上传用户头像的url={}", imageFolder, fileUrl);
            //更新userInfo中用户头像信息
            UserInfo userInfo = new UserInfo();
            userInfo.setUserid(userId);
            userInfo.setUserpic(fileUrl);
            int result = userInfoMapper.updateByUserIdSelective(userInfo);
            if (result > 0) {
                return Result.success(fileUrl);
            } else {
                return Result.error(result);
            }
        } catch (IOException ioe) {
            log.error(ioe.getMessage(), ioe);
            return Result.error("上传头像文件错误", "上传头像文件错误");
        }

    }

    @Override
    public List<BidPrivilege> findBidPrivilegesByUserId(String userId, int unstructuredData) {
        List<BidUserRoleXw> roleXws = bidUserRoleXwMapper.findRolesByUserId(userId);
        if (!CollectionUtils.isEmpty(roleXws)) {
            List<Long> roleIds = roleXws.stream().map(BidUserRoleXw::getRoleId).collect(Collectors.toList());
            List<BidRolePrivXw> rolePrivXws = bidRolePrivXwMapper.findPrivilsByRoleIds(roleIds);
            List<Integer> privilegeIds = rolePrivXws.stream().map(BidRolePrivXw::getPrivilegeId).distinct().collect(Collectors.toList());
            if (CollectionUtils.isEmpty(privilegeIds)) {
                return Collections.emptyList();
            }
            //查询出用户所有权限
            List<BidPrivilege> privileges = bidPrivilegeMapper.findPrivilegesByIds(privilegeIds);
            return privileges;
        }
        return null;
    }

}







